<template>
  <el-form ref="formRef" :class="{ 'c-form-text': textMode }" :model="data" :rules="rules" :label-width="labelWidth"
    :label-position="labelPosition" status-icon @change="onFormChange" v-loading="showLoading && isLoading">
    <slot></slot>
    <el-form-item v-if="showSaveButton">
      <el-button type="primary" @click="save()">保存</el-button>
    </el-form-item>
  </el-form>
</template>
<script setup>
import api from "@/api/common/common";
import {
  ref,
  reactive,
  onMounted,
  nextTick,
  useTemplateRef
} from "vue";
import { objDeepCopy } from "@/utils/common";
import { ElMessage, ElMessageBox, ElNotification } from "element-plus";

const props = defineProps({
  idKey: {
    type: String,
    default: "id",
  },
  showLoading: {
    type: Boolean,
    default: true,
  },
  labelWidth: {
    type: String,
    default: "85px",
  },
  labelPosition: {
    type: String,
    default: undefined,
  },
  showSaveButton: {
    type: Boolean,
    default: false,
  },
  textMode: {
    type: Boolean,
    default: false,
  },
  //表单验证规则
  rules: {
    type: Object,
    default: () => ({}),
  },
  data: {
    type: Object,
    default: () => ({}),
  },
  saveFunc: {
    type: Function,
    default: undefined,
  },
  confirmOnSave: {
    type: Boolean,
    default: false,
  },
  //保存之前，返回true进行保存，返回false不进行保存
  beforeSave: {
    type: Function,
    default: undefined,
  },
  confirmSaveText: {
    type: String,
    default: "您确定要保存吗？",
  },
  //获取数据函数
  getDataFunc: {
    type: Function,
    default: undefined,
  },
  getGuidOnCreate: {
    type: Boolean,
    default: false,
  },
  savedMessage: {
    type: String,
    default: "保存成功",
  },
});

const emits = defineEmits([
  "detailed",
  "edited",
  "data-got",
  "saved",
  "created",
]);
const isChange = ref(false);
const initData = ref({});
const isLoading = ref(false);
const isSaved = ref(false);
const isEdit = ref(false);

const formRef = useTemplateRef("formRef");
//在表单字段变更时
function onFormChange() {
  isChange.value = true;
}
function reset() {
  isSaved.value = false;
  isChange.value = false;
  setData(initData.value);
  clearValidate();
}
async function getGuid() {
  isLoading.value = true;
  let res = await api.getGuid();
  props.data.guid = res.data;
  isLoading.value = false;
}
function clearValidate() {
  nextTick(() => {
    formRef.value && formRef.value.clearValidate();
  });
}
function setData(data) {
  let tempData = objDeepCopy(data);
  for (let key in tempData) {
    if (typeof props.data[key] != "undefined") {
      props.data[key] = tempData[key];
    }
  }
}
function reload() {
  return getData(props.data[props.idKey]);
}
async function getData(id) {
  if (!getDataFunc) {
    alert("请指定form组件上get-data-func属性对应的函数");
    return false;
  }
  isLoading.value = true;
  try {
    let res = await getDataFunc(id);
    setData(res.data);
    clearValidate();
    isLoading.value = false;
    nextTick(() => {
      emits("data-got", res.data);
    });
    return res;
  } catch (error) {
    isLoading.value = false;
    console.log(error);
    return false;
  }
}
function change(isChange = true) {
  isChange.value = isChange;
}
async function validate() {
  return await new Promise((resolve) => {
    formRef.validate((valid) => {
      if (!valid) {
        ElNotification({
          title: "提示",
          message: "请检查相关字段（红色）填写是否规范",
          type: "warning",
          position: "top-left",
        })
        // this.$notify({
        //   title: "提示",
        //   message: "请检查相关字段（红色）填写是否规范",
        //   type: "warning",
        //   position: "top-left",
        // });
      }
      resolve(valid);
    });
  });
}
async function save(isForce = false) {
  if (!saveFunc) {
    alert("请指定form公共组件上save-func属性对应的函数！");
    return false;
  }
  if (isForce != true && !(await validate())) {
    return false;
  }

  if (props.beforeSave) {
    isLoading.value = true;
    if (!(await beforeSave())) {
      isLoading.value = false;
      return false;
    }
    isLoading.value = false;
  }
  if (props.confirmOnSave) {
    try {
      await ElMessageBox({
        title: "确认",
        message: props.confirmSaveText,
        type: "warning",
        showCancelButton: true,
      })
      // await this.$msgbox({
      //   title: "确认",
      //   message: props.confirmSaveText,
      //   type: "warning",
      //   showCancelButton: true,
      // });
    } catch (error) {
      return false;
    }
  }
  isLoading.value = true;
  try {
    let res = await saveFunc(props.data);
    if (res.code != 0) {
      return;
    }
    if (props.data[props.idKey] != undefined && !isEdit.value) {
      props.data[props.idKey] = res.data;
    }
    isEdit.value = true;
    isSaved.value = true;
    isChange.value = false;
    ElMessage({
      message: props.savedMessage,
      type: "success",
    });
    emits("saved");
    isLoading.value = false;
    return res;
  } catch (error) {
    console.log(error);
    isLoading.value = false;
    return false;
  }
}
async function create(data = null) {
  isEdit.value = false;
  if (data) {
    setData(data);
    clearValidate();
  }
  if (getGuidOnCreate) {
    await getGuid();
  }
  emits("created", data);
}
//编辑表单，会触发edit-opened事件
async function edit(data) {
  isEdit.value = true;
  setData(data);
  clearValidate();
  emits("edited", data);
}
//根据Id打开编辑表单，会触发edited事件
async function editById(id) {
  isEdit.value = true;
  let res = await getData(id);
  emits("edited", res.data);
}
//打开详情窗口，会触发detailed事件
function detail(data) {
  setData(data);
  nextTick(() => {
    emits("detailed", data);
  });
}
//根据Id打开详情窗口，会触发detailed事件
async function detailById(id) {
  await getData(id);
  emits("detailed", res.data);
}
function loading(isLoading = true) {
  isLoading.valueOf = isLoading;
}

onMounted(() => {
  initData.value = objDeepCopy(props.data);
});
</script>